﻿#!/usr/bin/env python
#coding=utf-8

import os
import argparse
import shutil

class CommandError( Exception ):
	def __init__( self, string ):
		self.string = string

	def __str__( self ):
		return self.string

class CumulativeError( Exception ):
	def __init__( self, arr ):
		self.arr = arr

	def __str__( self ):
		return self.arr

translit = dict(zip(u"абвгдеёзийклмнопрстуфхьъ", "abvgdeeziyklmnoprstufh'~"))
translit.update({u'ц': 'tz'                              , u'ч': 'ch'              , u'ш': 'sh'                    , u'ы': 'yi',
                 u'э': 'ye'                              , u'ю': 'ju'              , u'я': 'ja'                    , u' ': '_',		u'ж': 'zh'})


def translate_name( encoding, name ):
	decoded = name.decode( encoding ).lower()
	mapped = ''.join([translit.get(x, x) for x in decoded]).encode( encoding )
	return mapped

def transliterate_walk( encoding, src, dst ):
	names = os.listdir( src )
	files = []

	try:
		os.makedirs( dst )
	except OSError:
		pass

	for name in names:
		srcname = os.path.join( src, name )

		dstname = os.path.join( dst, translate_name( encoding, name ) )

		if os.path.isdir( srcname ):
			for entry in transliterate_walk( encoding, srcname, dstname ):
				yield entry

		else:
			files.append( (srcname, dstname) )

	yield src, dst, files

def copytranstree (encoding, src, dst):

	errors = []

	for src_path, dest_path, filenames in transliterate_walk( encoding, src, dst ):
		try:
			os.makedirs( dest_path )
		except OSError:
			pass

		for src_filename, dest_filename in filenames:
			try:
				shutil.copy2( src_filename, dest_filename )
			except (IOError, os.error) as why:
				errors.append( (src_filename, dest_filename, str(why) ) )
		try:
			shutil.copystat( src, dst )
		except OSError as why:
			errors.append( (src_path, dst_path, str( why ) ) )

def main():
	parser = argparse.ArgumentParser(description='Copy directory tree with transliterated pathnames')
	parser.add_argument('-e'                               ,'--encoding'             , help='File system encoding'   , default='utf-8'	, metavar='utf-8 | cp1251')
	parser.add_argument('-s'                               ,'--src'                  , help='Source folder name'     , default='./' )
	parser.add_argument('-d'                               ,'--dst'                  , help='Destination folder name', default='./')

	input_parametres = parser.parse_args()

	try:
		src = os.path.abspath( input_parametres.src )
		dst = os.path.abspath( input_parametres.dst )
		encoding = input_parametres.encoding

		if not os.path.exists( dst ):
			dstname =  translate_name( input_parametres.encoding, dst )
			os.makedirs( dstname )
			dst = os.path.abspath( dstname )

		if not os.path.exists( src ):
			raise CommandError('%s does not exist' % src)
		if os.path.isfile( dst ):
			raise CommandError('%s is a file' % dest)

		copytranstree( input_parametres.encoding, src, dst )

	except CommandError, err:
		print err
	except UnicodeDecodeError:
		print "Illegal encoding %s. Try another one" % encoding
	except Exception,	err:
		print err

if __name__ == '__main__':
	main()
